﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.ApplicationModel.Resources.Core;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using System.Collections.Specialized;
using System.Xml.Linq;

namespace Recipe.Data
{
    /// <summary>
    /// Base class for <see cref="RecipeDataItem"/> and <see cref="RecipeDataGroup"/> that
    /// defines properties common to both.
    /// </summary>
    [Windows.Foundation.Metadata.WebHostHidden]
    public abstract class RecipeDataCommon : Recipe.Common.BindableBase
    {
        private static Uri _baseUri = new Uri("ms-appx:///");

        public RecipeDataCommon(String uniqueId, String title, String subtitle, String imagePath, String description)
        {
            this._uniqueId = uniqueId;
            this._title = title;
            this._subtitle = subtitle;
            this._description = description;
            this._imagePath = imagePath;
        }

        private string _uniqueId = string.Empty;
        public string UniqueId
        {
            get { return this._uniqueId; }
            set { this.SetProperty(ref this._uniqueId, value); }
        }

        private string _title = string.Empty;
        public string Title
        {
            get { return this._title; }
            set { this.SetProperty(ref this._title, value); }
        }

        private string _subtitle = string.Empty;
        public string Subtitle
        {
            get { return this._subtitle; }
            set { this.SetProperty(ref this._subtitle, value); }
        }

        private string _description = string.Empty;
        public string Description
        {
            get { return this._description; }
            set { this.SetProperty(ref this._description, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;
        public ImageSource Image
        {
            get
            {
                if (this._image == null && this._imagePath != null)
                {
                    this._image = new BitmapImage(new Uri(RecipeDataCommon._baseUri, this._imagePath));
                }
                return this._image;
            }

            set
            {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }

        public void SetImage(String path)
        {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }
    }

    /// <summary>
    /// Generic item data model.
    /// </summary>
    public class RecipeDataItem : RecipeDataCommon
    {
        public RecipeDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, String content, RecipeDataGroup group)
            : base(uniqueId, title, subtitle, imagePath, description)
        {
            this._content = content;
            this._group = group;
        }

        private string _content = string.Empty;
        public string Content
        {
            get { return this._content; }
            set { this.SetProperty(ref this._content, value); }
        }

        private RecipeDataGroup _group;
        public RecipeDataGroup Group
        {
            get { return this._group; }
            set { this.SetProperty(ref this._group, value); }
        }
    }

    /// <summary>
    /// Generic group data model.
    /// </summary>
    public class RecipeDataGroup : RecipeDataCommon
    {
        public RecipeDataGroup(String uniqueId, String title, String subtitle, String imagePath, String description)
            : base(uniqueId, title, subtitle, imagePath, description)
        {
        }

        private ObservableCollection<RecipeDataItem> _items = new ObservableCollection<RecipeDataItem>();
        public ObservableCollection<RecipeDataItem> Items
        {
            get { return this._items; }
        }
    }

    /// <summary>
    /// Creates a collection of groups and items with hard-coded content.
    /// </summary>
    public sealed class RecipeData
    {
        public static string RecipeGroupId = string.Empty;
        private static RecipeData dataSource = new RecipeData();
        private ObservableCollection<RecipeDataGroup> _itemGroups = new ObservableCollection<RecipeDataGroup>();
        public ObservableCollection<RecipeDataGroup> ItemGroups
        {
            get { return this._itemGroups; }
        }

        public static IEnumerable<RecipeDataGroup> GetGroups(string uniqueId)
        {
            return dataSource.ItemGroups.Where(i=>i.UniqueId==uniqueId);
        }
        public RecipeData() { }
        public RecipeData(string gourpId)
        {
            XDocument xmlDoc = XDocument.Load("Data\\RecipeData.xml");

            var groups = from g in xmlDoc.Descendants("groups").Elements("group")
                         where g.Attribute("id").Value == gourpId.Split('-')[1]
                         select new RecipeDataGroup(
                             "Group-" + g.Attribute("id").Value,
                             g.Attribute("title").Value,
                             g.Element("subtitle").Value,
                             g.Attribute("img").Value,
                             g.Element("description").Value);


            foreach (var g in groups)
            {
                var rGroup = from gr in xmlDoc.Descendants("groups").Elements("group")
                             where gr.Attribute("id").Value == g.UniqueId.Split('-')[1]
                             select gr;
                var items = from i in rGroup.Descendants("items").Elements("item")
                             select new RecipeDataItem(
                                    g.UniqueId + "-item-" + i.Attribute("id").Value, //Group-3-Item-2
                                     i.Attribute("title").Value,
                                     i.Element("subtitle").Value,
                                     i.Attribute("imgTitle").Value,                                   
                                     i.Element("content").Value,
                                     i.Element("description").Value,
                                     null
                                   );

                foreach (var i in items)
                {
                    g.Items.Add(i);
                }

                this.ItemGroups.Add(g);
            }                 
        }
    }
}
